home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1997 / MacHack 1997.toast / Hacks / Hacks ’96 / Adobe Illustrator Plug-ins / AIQuickCapture Project / source / raster utils.c < prev   
Text File  |  1996-06-22  |  9KB  |  315 lines

  1. /* ---------------------------------------------------------------------------
  2.  
  3.     raster utils.c
  4.  
  5.     Copyright (c) 1995-6 Adobe Systems Incorporated
  6.     All Rights Reserved
  7.     
  8.    --------------------------------------------------------------------------- */
  9.  
  10.  
  11. #include "common.h"
  12. #include "raster utils.h"
  13.  
  14. #define        kRowBytesMask            0x3fff
  15.  
  16.  
  17.  
  18. // Creates an offscreen GWorld and locks down its pixels
  19. extern FXErr createOffscreen( GWorldPtr *offscreen, Rect *bounds, short depth )
  20. {
  21.     QDErr err;
  22.     FXErr error = kNoErr;
  23.     PixMapHandle offscreenPMHandle;
  24.     
  25.     // create offscreen graphics world
  26.     err = NewGWorld(offscreen, depth, bounds, nil, nil, 0);
  27.  
  28.     if (!offscreen || (err != kNoErr))
  29.        error = kMyOffscreenErr;
  30.    
  31.     offscreenPMHandle = GetGWorldPixMap(*offscreen);
  32.     if ( !LockPixels(offscreenPMHandle) ) {
  33.         error = kMyOffscreenErr;
  34.         DisposeGWorld(*offscreen);
  35.         }
  36.  
  37.     RectRgn( (*offscreen)->clipRgn, &(*offscreen)->portRect);
  38.         
  39.     return error;
  40. }
  41.  
  42.  
  43.  
  44. // Unlock any locked pixels in a GWorld and dipose of it
  45. extern void disposeOffscreen( GWorldPtr *offscreen )
  46. {
  47.     PixMapHandle offscreenPMHandle = GetGWorldPixMap(*offscreen);
  48.  
  49.     // unlock & release the pixel image
  50.     UnlockPixels(offscreenPMHandle);
  51.     DisposeGWorld(*offscreen);
  52.     *offscreen = nil;
  53. }
  54.  
  55.  
  56.  
  57.  
  58. // Given a GWorld and a dpi, this creates the appropriate raster art object to receive
  59. // it and fills in a copy request record to be using in transfering the pixels.  
  60. extern FXErr newRasterArtForGWorld( GWorldPtr theWorld, Fixed dpi,
  61.              MakeGWorldTileRequest *request, AIArtHandle *newRaster ) {
  62.  
  63.     FXErr             error = kNoErr;
  64.     AIRasterRecord    rasterInformation;
  65.     AIArtHandle        theRasterObject;        
  66.     Rect             nBounds;
  67.     Rect            bounds;
  68.     FixedPoint        inverseScale, center;
  69.     FixedMatrix        rasterMatrix;
  70.     Fixed             scale;
  71.     
  72.  
  73.     error = kNoErr;
  74.  
  75.     // Raster objects have a base resolution of 72dpi.  The resolution can be changed 
  76.     // by increasing the image bounds by a scale and using the inverse scale as a 
  77.     // scaling factor.  For instance, to do 144 dpi, uses bounds*2 with a scale of 50%.
  78.     // bounds * scale and kFixedOne/scale
  79.     scale = sMath->FixedDiv( dpi, _ShortToFixed( 72 ));
  80.  
  81.     // Make a uninitialized raster object
  82.     error = sArt->NewArt( kRasterArt, kPlaceAboveAll, nil, &theRasterObject );
  83.     if ( !error ) {
  84.  
  85.         // an init it...
  86.         error = sRaster->GetRasterInfo( theRasterObject, &rasterInformation );
  87.         if ( !error ) {
  88.  
  89.             // get the bounds to create the gworld and raster art
  90.             bounds = ((GrafPtr)theWorld)->portRect;
  91.             nBounds.top = 0;
  92.             nBounds.left = 0;
  93.             nBounds.bottom = _FixedTruncToShort( sMath->FixedMul( scale, _ShortToFixed(bounds.bottom) ) );// + 1;
  94.             nBounds.right = _FixedTruncToShort( sMath->FixedMul( scale, _ShortToFixed(bounds.right) ) );// + 1;
  95.  
  96.             rasterInformation.colorSpace = kRGBColorSpace;
  97.             error = GetColorSpaceDepth( rasterInformation.colorSpace, &rasterInformation.bitsPerPixel );
  98.             
  99.             rasterInformation.bounds = nBounds;
  100.             rasterInformation.byteWidth = (rasterInformation.bounds.right * (rasterInformation.bitsPerPixel / 8));
  101.             
  102.             error = sRaster->SetRasterInfo( theRasterObject, &rasterInformation );
  103.             if ( !error ) {
  104.                 // now set the scale of the the raster object
  105.                 inverseScale.h = sMath->FixedDiv( kFixedOne, scale );
  106.                 inverseScale.v = sMath->FixedDiv( kFixedOne, scale );
  107.                 
  108.     error = sDocumentView->GetDocumentViewCenter( ¢er );
  109.  
  110.                 sMath->FixedMatrixSetScale( &rasterMatrix, inverseScale.h, inverseScale.v );
  111.     sMath->FixedMatrixConcatTranslate( &rasterMatrix, center.h, center.v );
  112.                 error = sRaster->SetRasterMatrix( theRasterObject, &rasterMatrix );                    
  113.                 }
  114.     
  115.             // if successful, fill in parts of the copy request record
  116.             if (!error) {
  117.                 request->fRasterBounds = rasterInformation.bounds;
  118.                 request->fSelectionBounds.top = _ShortToFixed( nBounds.bottom );
  119.                 request->fSelectionBounds.left = _ShortToFixed( nBounds.right );
  120.                 request->fSelectionBounds.bottom = kFixedZero;
  121.                 request->fSelectionBounds.right = kFixedZero;
  122.     
  123.                 request->fScale = scale;
  124.                 request->fColorSpace = rasterInformation.colorSpace;
  125.                 request->fWorld = theWorld;
  126.                 }
  127.             }
  128.         if (error)
  129.             sArt->DisposeArt( theRasterObject );
  130.         }
  131.     
  132.     if (error)
  133.         *newRaster = nil;
  134.     else
  135.         *newRaster = theRasterObject;
  136.  
  137.     return( error );    
  138. }
  139.     
  140.  
  141.  
  142.     
  143. // given a raster art object and copy request record, copy a gworld to the Illustrator object    
  144. FXErr copyGWorldToRasterArt( MakeGWorldTileRequest    *request, AIArtHandle destRaster ) {
  145.     FXErr error = kNoErr;
  146.     short sliceWidth, sliceHeight;
  147.     PixMapHandle offscreenPMHandle;
  148.     CGrafPtr savedWorld;
  149.     GDHandle savedDevice;
  150.  
  151.     GetGWorld( &savedWorld, &savedDevice );
  152.     SetGWorld( request->fWorld, nil );
  153.  
  154.     offscreenPMHandle = GetGWorldPixMap( request->fWorld );
  155.     LockPixels( offscreenPMHandle );
  156.     request->fWorldTile.data = GetPixBaseAddr( offscreenPMHandle );
  157.  
  158.     // This is the height and width to be set at a given time
  159.     sliceWidth = (request->fWorldSlice.right - request->fWorldSlice.left);
  160.     sliceHeight = (request->fWorldSlice.bottom - request->fWorldSlice.top);
  161.  
  162.     // and is used to determine the slice (subset) of the whole which is to be copied
  163.     request->fRasterSlice.top = request->fRasterBounds.top;
  164.     request->fRasterSlice.bottom = request->fRasterBounds.top + sliceHeight;
  165.  
  166.     // if you were doing a using DrawArt() into a series of RasterArt tiles
  167.     // you would do something like this to set the origin relative to which
  168.     // the art is drawn, moving it with the slice horizontally and vertically across
  169.     // the tile.  (Not used here since this basically a GWorld transfer.)
  170.     // request->fDrawArt.origin.v = request->fSelectionBounds.top;
  171.     
  172.     while ( !error && (request->fRasterSlice.top < request->fRasterBounds.bottom) ) {
  173.  
  174.         request->fRasterSlice.left = request->fRasterBounds.left;
  175.         request->fRasterSlice.right = request->fRasterSlice.left + sliceWidth;
  176.         
  177.         // see the DrawArt() comment above
  178.         // request->fDrawArt.origin.h = request->fSelectionBounds.left;
  179.         
  180.         while ( !error && (request->fRasterSlice.left < request->fRasterBounds.right) ) {
  181.  
  182.             // copy the slices horizontally
  183.             error = sRaster->SetRasterTile( destRaster, &request->fRasterSlice, &request->fWorldTile, &request->fWorldSlice );
  184.             
  185.             // and increment for the next slice
  186.             if ( !error ) {
  187.                 // see the DrawArt() comment above
  188.                 // request->fDrawArt.origin.h += sliceWidth;
  189.                 request->fRasterSlice.left += sliceWidth;
  190.                 request->fRasterSlice.right += sliceWidth;
  191.                 }
  192.             }
  193.  
  194.         if ( !error ) {
  195.             // see the DrawArt() comment above
  196.             // request->fDrawArt.origin.v += sliceHeight;
  197.             request->fRasterSlice.top += sliceHeight;
  198.             request->fRasterSlice.bottom += sliceHeight;
  199.             }                    
  200.         }
  201.         
  202.     SetGWorld( savedWorld, savedDevice );
  203.  
  204.     return error;
  205. }
  206.  
  207.  
  208.  
  209.  
  210.  
  211. extern FXErr CreateGWorldTile( MakeGWorldTileRequest    *request )
  212.  
  213. {
  214.  
  215.     // Locals
  216.     FXErr                     error;
  217.     PixMapHandle            pixelMapHandle;
  218.         
  219.     error = kNoErr;
  220.         
  221.     switch ( request->fColorSpace ) {
  222.     
  223.         case kGrayColorSpace:
  224.             request->fWorldSlice.front = 0;
  225.             request->fWorldSlice.back = 1;
  226.             request->fRasterSlice.front = 0;
  227.             request->fRasterSlice.back = 1;
  228.             request->fWorldTile.colBytes = 1;
  229.             request->fWorldTile.channelInterleave[0] = 0;    // Identical Mapping
  230.         break;
  231.         
  232.         case kRGBColorSpace:
  233.             request->fWorldSlice.front = 1;
  234.             request->fWorldSlice.back = 4;
  235.             request->fRasterSlice.front = 0;
  236.             request->fRasterSlice.back = 3;
  237.             request->fWorldTile.colBytes = 4;                // GWorlds don't do 24 bit, 16 or 32 only
  238.             request->fWorldTile.channelInterleave[0] = 0;    // Alpha channel is ignored by setting wordSlice.front to 1
  239.             request->fWorldTile.channelInterleave[1] = 0;    // Map 32-bit red position to 24-bit red position
  240.             request->fWorldTile.channelInterleave[2] = 1;    // Map 32-bit green position to 24-bit green position
  241.             request->fWorldTile.channelInterleave[3] = 2;    // Map 32-bit blue position to 24-bit blue position
  242.         break;                                            
  243.         
  244.         case kCMYKColorSpace:
  245.             request->fWorldSlice.front = 0;
  246.             request->fWorldSlice.back = 4;
  247.             request->fRasterSlice.front = 0;
  248.             request->fRasterSlice.back = 4;
  249.             request->fWorldTile.colBytes = 4;
  250.             request->fWorldTile.channelInterleave[0] = 0;    // Identical Mapping
  251.             request->fWorldTile.channelInterleave[1] = 1;
  252.             request->fWorldTile.channelInterleave[2] = 2;
  253.             request->fWorldTile.channelInterleave[3] = 3;
  254.         break;
  255.     
  256.     }
  257.     
  258.     request->fWorldSlice.top = request->fRasterBounds.top;
  259.     request->fWorldSlice.left = request->fRasterBounds.left;
  260.     request->fWorldSlice.bottom = request->fRasterBounds.bottom;
  261.     request->fWorldSlice.right = request->fRasterBounds.right;
  262.     
  263.     request->fWorldTile.data = nil;
  264.     request->fWorldTile.bounds = request->fWorldSlice;
  265.     request->fWorldTile.bounds.front = 0;
  266.     request->fWorldTile.bounds.back = request->fWorldTile.colBytes;
  267.     pixelMapHandle = GetGWorldPixMap( request->fWorld );
  268.     request->fWorldTile.rowBytes = ((*pixelMapHandle)->rowBytes & kRowBytesMask);
  269.     request->fWorldTile.planeBytes = 0;        
  270.     
  271.     return( error );    
  272. }
  273.  
  274.  
  275.  
  276.  
  277.  
  278. extern FXErr GetColorSpaceDepth(
  279.  
  280.     int16        colorSpace,
  281.     int16        *depthPointer )
  282.     
  283. {
  284.  
  285.     // Locals
  286.     
  287.         FXErr                    error;
  288.         
  289.     error = kNoErr;
  290.     
  291.     switch ( colorSpace ) {
  292.     
  293.         case kGrayColorSpace:
  294.             *depthPointer = 8;
  295.         break;
  296.         
  297.         case kRGBColorSpace:
  298.             *depthPointer = 24;
  299.         break;
  300.         
  301.         case kCMYKColorSpace:
  302.             *depthPointer = 32;
  303.         break;
  304.         
  305.         default:
  306.             *depthPointer = 0;
  307.             error = kRasterTypeNotSupportedErr;
  308.         break;
  309.     
  310.     }
  311.     
  312.     return( error );
  313.  
  314. }
  315.